use std::sync::Arc;

use sqlx::{migrate::MigrateDatabase, sqlite::SqliteQueryResult, Sqlite, SqlitePool};


pub(super) mod user;
pub(crate) mod user_operations;


pub(crate) struct  Connection{
    sqlite_pool:Option<sqlx::SqlitePool>,
    initialized:bool,
}

const USERDB:&'static str = "sqlite:user.db";

impl Connection{
    fn new()->Self{
        Connection{
        sqlite_pool:Option::None,
        initialized:false,
        }
    }

     pub(crate) async fn get_instance()->Arc<Connection>{

        static mut INSTANCE:Option<Arc<Connection>> = None;

        let mut conn = Connection::new();
        conn.initialize().await;
        unsafe {
            INSTANCE.get_or_insert_with(|| {
                // Rc::new(conn)
                // Arc::new(Mutex::new(conn))
                Arc::new(conn)
            }).clone()
        }
    }

    pub(crate) fn get_sqlite_pool(& self)->&Option<sqlx::SqlitePool>{
        &self.sqlite_pool
    }
    
     async fn initialize(&mut self){
        if !self.initialized {
            self.sqlite_pool = match sqlite_pool(USERDB.to_string()).await{
                Ok(pool)=>{
                    println!("sqlite pool initialized");
                    Some(pool)
                },
                Err(msg)=>{
                    println!("{}",msg);
                    println!("sqlite pool initialization failed");
                    Option::None
                }
            };
        }


            
    }


    
}

// 传入db_url，它期望返回一个SqliteQueryResult
async fn create_schema(db_url:&str) -> Result<SqliteQueryResult, sqlx::Error> {
    // 创建一个连接到db_url的连接池
    let pool = SqlitePool::connect(db_url).await?;
    // 定义数据库表
    let qry = include_str!("../../migrations/create_table.sql");
    // 运行
    let result = sqlx::query(qry).execute(&pool).await;
    // 关闭连接池
    pool.close().await; 
    result
}

  async fn  sqlite_pool(str:String) ->Result<SqlitePool,String>{
    // let from_url="sqlite:user.db";

    // let manager = SqliteConnectionManager::file(str);
    // let pool =  r2d2::Pool::new(manager).unwrap();
    // return Ok(pool);
    let from_url = str.as_str();
    // 如果数据库不存在，则创建它。
    if !Sqlite::database_exists(&from_url).await.unwrap_or(false){
        Sqlite::create_database(&from_url).await.unwrap();
        //如果存在，则调用create_schema
        match create_schema(&from_url).await {
            // 如果一切顺利，打印OK…否则panic
            Ok(_) => println!("database created succesfully"),
            Err(e) => panic!("{}", e)
        }
    }


    // let options = SqliteConnectOptions::new().filename(from_url);
    let pool = SqlitePool::connect(from_url).await;
    if let Ok(pool) = pool {
        println!("Connected to the database!");
        Ok(pool)
    } else {
        println!("Failed to connect to the database.");
        return Err(String::from("connection error"));
    }
    // return Ok(pool);
  }
